<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>上拉加载更多</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        #main {
            width: 100%;
        }

        #main div {
            width: 100%;
            height: 60px;
            padding-left: 5%;
            padding-right: 5%;
        }

        .loading {
            width: 150px;
            height: 10px;
            margin: 20px auto;
        }

        .loading span {
            display: inline-block;
            width: 10px;
            height: 100%;
            margin-right: 3px;
            border-radius: 50%;
            background: #e74c3c;
            -webkit-animation: load 1.04s ease infinite;
        }

        .loading span:last-child {
            margin-right: 0px;
        }

        @-webkit-keyframes load {
            0% {
                opacity: 1;
            }
            100% {
                opacity: 0;
            }
        }

        .loading span:nth-child(1) {
            -webkit-animation-delay: 0.13s;
        }

        .loading span:nth-child(2) {
            -webkit-animation-delay: 0.26s;
        }

        .loading span:nth-child(3) {
            -webkit-animation-delay: 0.39s;
        }

        .loading span:nth-child(4) {
            -webkit-animation-delay: 0.52s;
        }

        .loading span:nth-child(5) {
            -webkit-animation-delay: 0.65s;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <div id="main">
        <template v-for="items in  listData">
            <div>{{items.text}}</div>
        </template>
    </div>
    <div class="loading" id="loader" v-show="loadingState">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div v-show="allLoading">
        <p style="text-align: center;">我是有底线的~~</p>
    </div>
</div>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            //加载是否完毕
            loadingState: false,
            //当前加载数量
            currentCount: 0,
            //是否全部加载完毕
            allLoading: false,
            //数据
            listData: []
        },
        async mounted() {
            let itemCount = this.getUserClientHeight();
            await this.getListData();
            while (this.listData.length < itemCount) {
                await this.getListData();
            }
            window.addEventListener('scroll', this.toScroll);
        },
        destroyed() {
            window.removeEventListener('scroll', this.toScroll);
        },
        methods: {
            ListData() {
                return new Promise((resolve, reject) => {
                    const err = null;
                    setTimeout(() => {
                        if (!err) {
                            resolve({
                                code: 200,
                                totalCount: 30,
                                textList: [
                                    {text: 'new content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'},
                                    {text: 'new content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'},
                                    {text: 'new content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'},
                                    {text: 'new content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'},
                                    {text: 'new content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'},
                                    {text: 'NEW content Lorem ipsum dolor sit amet, con sec tetur adipisicing elit'}
                                ]
                            })
                        } else reject(err)
                    }, 60)
                })
            },
            getListData() {
                this.loadingState = true;
                return this.ListData().then(res => {
                    this.listData = this.listData.concat(res.textList)
                    console.log(this.listData)
                    this.totalCount = res.totalCount
                }).catch(err => {
                    console.log(err)
                }).finally(() => {
                    this.loadingState = false;
                });
            },
            //获取设备高度
            getUserClientHeight() {
                let deviceHeight = document.documentElement.clientHeight || window.innerHeight || document.body.clientHeight
                return Math.ceil(deviceHeight / 60);
            },

            //获取滚动条当前的位置
            getScrollTop() {
                let scrollTop = 0;
                if (document.documentElement && document.documentElement.scrollTop) {
                    scrollTop = document.documentElement.scrollTop;
                } else if (document.body) {
                    scrollTop = document.body.scrollTop;
                }
                return scrollTop;
            },

            //获取当前可视范围的高度
            getClientHeight() {
                let clientHeight = 0;
                if (document.body.clientHeight && document.documentElement.clientHeight) {
                    clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight);
                } else {
                    clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
                }
                return clientHeight;
            },

            //获取文档完整的高度
            getScrollHeight() {
                return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
            },

            //滑动时
            async toScroll() {
                if (this.getScrollTop() + this.getClientHeight() >= this.getScrollHeight()) {
                    if (!this.loadingState) {
                        if (this.listData.length < this.totalCount) {
                            await this.getListData();
                        } else {
                            this.allLoading = true;
                        }
                    }
                }
            }
        }
    })
</script>
</body>
</html>
